"""
xlcig Notebook Visualization Platform
Enterprise Data Analytics Dashboard

Professional data visualization tool for enterprise users:
- Multi-file batch processing (.ipynb, .csv, .xlsx)
- Automated chart generation and analysis
- Enterprise-grade interface design
- Professional dashboard layout
"""

import gradio as gr
import pandas as pd
import json
import os
import tempfile
import traceback
from typing import Dict, List, Optional, Tuple, Any
import concurrent.futures
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.express as px

from file_parser import FileParser
from chart_generator import ChartGenerator


class XlcigNotebookApp:
    """Enterprise-grade data visualization dashboard"""
    
    def __init__(self):
        self.file_parser = FileParser()
        self.chart_generator = ChartGenerator()
        self.current_dataframes = {}
        self.current_language = 'zh'
        
    def process_multiple_files(self, files, language: str) -> Tuple[str, str, str]:
        """Process multiple uploaded files and generate analysis dashboard"""
        if not files or len(files) == 0:
            return "", "", "Please upload data files" if language == 'en' else "请上传数据文件"
        
        try:
            all_dataframes = {}
            file_info = []
            
            # Process each file
            for file in files:
                if file is None:
                    continue
                    
                try:
                    # Parse individual file
                    file_dataframes = self.file_parser.load_file(file.name)
                    
                    # Add to global collection
                    filename = os.path.splitext(os.path.basename(file.name))[0]
                    for df_name, df in file_dataframes.items():
                        if not df.empty:
                            key = f"{filename}_{df_name}" if df_name != filename else filename
                            all_dataframes[key] = df
                            file_info.append({
                                'name': key,
                                'rows': df.shape[0],
                                'columns': df.shape[1],
                                'size': f"{df.memory_usage(deep=True).sum() / 1024:.1f} KB"
                            })
                            
                except Exception as e:
                    print(f"Error processing {file.name}: {e}")
                    continue
            
            if not all_dataframes:
                return "", "", "No valid data found" if language == 'en' else "未找到有效数据"
            
            # Store dataframes
            self.current_dataframes = all_dataframes
            
            # Generate data summary table
            summary_table = self.generate_data_summary(file_info, language)
            
            # Generate analysis dashboard
            dashboard_html = self.generate_analysis_dashboard(all_dataframes, language)
            
            status_msg = f"Successfully processed {len(all_dataframes)} datasets" if language == 'en' else f"成功处理 {len(all_dataframes)} 个数据集"
            
            return summary_table, dashboard_html, status_msg
            
        except Exception as e:
            error_msg = f"Processing error: {str(e)}" if language == 'en' else f"处理错误: {str(e)}"
            print(f"Multiple file processing error: {traceback.format_exc()}")
            return "", "", error_msg
    
    def generate_data_summary(self, file_info: List[Dict], language: str) -> str:
        """Generate data summary table"""
        
        if language == 'zh':
            headers = ["数据集名称", "行数", "列数", "内存占用"]
        else:
            headers = ["Dataset Name", "Rows", "Columns", "Memory Usage"]
        
        # Create HTML table
        table_html = f"""
        <div class="data-summary-container">
            <h3 class="section-title">{"数据集概览" if language == 'zh' else "Dataset Overview"}</h3>
            <table class="data-summary-table">
                <thead>
                    <tr>
                        <th>{headers[0]}</th>
                        <th>{headers[1]}</th>
                        <th>{headers[2]}</th>
                        <th>{headers[3]}</th>
                    </tr>
                </thead>
                <tbody>
        """
        
        for info in file_info:
            table_html += f"""
                    <tr>
                        <td class="dataset-name">{info['name']}</td>
                        <td class="numeric">{info['rows']:,}</td>
                        <td class="numeric">{info['columns']}</td>
                        <td class="numeric">{info['size']}</td>
                    </tr>
            """
        
        table_html += """
                </tbody>
            </table>
        </div>
        """
        
        return table_html
    
    def generate_analysis_dashboard(self, dataframes: Dict[str, pd.DataFrame], language: str) -> str:
        """Generate enterprise analysis dashboard"""
        
        dashboard_html = f"""
        <div class="analysis-dashboard">
            <h3 class="section-title">{"数据分析仪表板" if language == 'zh' else "Data Analysis Dashboard"}</h3>
            <div class="dashboard-grid">
        """
        
        chart_count = 0
        for df_name, df in dataframes.items():
            if df.empty:
                continue
                
            try:
                # Get column info
                column_info = self.file_parser.get_column_info(df)
                numeric_cols = column_info['numeric_columns']
                categorical_cols = column_info['categorical_columns']
                
                # Generate charts for dataset
                charts = []
                
                # 1. Data distribution chart
                if categorical_cols and numeric_cols:
                    chart_path = self.generate_chart_safe(df, df_name, 'overview', 
                                                        categorical_cols[0], numeric_cols[0], language)
                    if chart_path:
                        charts.append(('Data Distribution', chart_path))
                
                # 2. Correlation analysis for numeric data
                if len(numeric_cols) >= 2:
                    chart_path = self.generate_chart_safe(df, df_name, 'heatmap', None, None, language)
                    if chart_path:
                        charts.append(('Correlation Analysis', chart_path))
                
                # 3. Statistical distribution
                if numeric_cols:
                    chart_path = self.generate_chart_safe(df, df_name, 'histogram', 
                                                        numeric_cols[0], None, language)
                    if chart_path:
                        charts.append(('Statistical Distribution', chart_path))
                
                # Add dataset panel
                if charts:
                    dashboard_html += f"""
                    <div class="dataset-panel">
                        <div class="panel-header">
                            <h4 class="dataset-title">{df_name}</h4>
                            <div class="dataset-stats">
                                <span class="stat-item">{df.shape[0]} rows</span>
                                <span class="stat-item">{df.shape[1]} columns</span>
                                <span class="stat-item">{len(numeric_cols)} numeric</span>
                                <span class="stat-item">{len(categorical_cols)} categorical</span>
                            </div>
                        </div>
                        <div class="charts-container">
                    """
                    
                    for chart_title, chart_path in charts:
                        dashboard_html += f"""
                        <div class="chart-panel">
                            <h5 class="chart-title">{chart_title}</h5>
                            <div class="chart-wrapper">
                                <img src="file://{chart_path}" alt="{chart_title}" class="chart-image" />
                            </div>
                        </div>
                        """
                        chart_count += 1
                    
                    dashboard_html += "</div></div>"
                
            except Exception as e:
                print(f"Error generating analysis for {df_name}: {e}")
                continue
        
        dashboard_html += f"""
            </div>
            <div class="dashboard-summary">
                <p>{"共生成" if language == 'zh' else "Generated"} {chart_count} {"个分析图表" if language == 'zh' else "analysis charts"}</p>
            </div>
        </div>
        """
        
        return dashboard_html
    
    def generate_chart_safe(self, df: pd.DataFrame, df_name: str, chart_type: str, 
                          x_col: Optional[str], y_col: Optional[str], language: str) -> Optional[str]:
        """Safely generate chart with error handling"""
        try:
            # Create appropriate title
            if chart_type == 'overview':
                title = f"{df_name} - Data Distribution"
            elif chart_type == 'heatmap':
                title = f"{df_name} - Correlation Matrix"
            elif chart_type == 'histogram':
                title = f"{df_name} - {x_col} Distribution"
            else:
                title = f"{df_name} - {chart_type.title()}"
            
            chart_path = self.chart_generator.generate_chart(
                df=df,
                chart_type=chart_type,
                x_col=x_col,
                y_col=y_col,
                theme='plotly_white',
                title=title,
                engine='plotly'
            )
            
            return chart_path
            
        except Exception as e:
            print(f"Error generating {chart_type} chart for {df_name}: {e}")
            return None
    
    def create_interface(self):
        """Create enterprise-grade interface"""
        
        with gr.Blocks(
            title="xlcig Notebook Enterprise Analytics Platform",
            theme=gr.themes.Base(),
            css="""
            /* Enterprise Theme CSS */
            .gradio-container {
                max-width: 1920px !important;
                margin: 0 auto;
                font-family: "Segoe UI", "Microsoft YaHei", Arial, sans-serif;
                background-color: #f8f9fa;
                padding: 0;
            }
            
            /* Header */
            .main-header {
                background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
                color: white;
                padding: 20px 40px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            
            .header-title {
                font-size: 28px;
                font-weight: 600;
                margin: 0;
                letter-spacing: -0.5px;
            }
            
            .header-subtitle {
                font-size: 14px;
                margin: 5px 0 0 0;
                opacity: 0.9;
                font-weight: 400;
            }
            
            /* Main Layout */
            .main-content {
                display: grid;
                grid-template-columns: 350px 1fr;
                gap: 30px;
                padding: 30px;
                min-height: calc(100vh - 120px);
            }
            
            /* Left Sidebar */
            .left-sidebar {
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                padding: 25px;
                height: fit-content;
            }
            
            .sidebar-section {
                margin-bottom: 25px;
            }
            
            .sidebar-title {
                font-size: 16px;
                font-weight: 600;
                color: #374151;
                margin: 0 0 15px 0;
                padding-bottom: 8px;
                border-bottom: 2px solid #e5e7eb;
            }
            
            /* File Upload Area */
            .upload-area {
                border: 2px dashed #d1d5db;
                border-radius: 8px;
                padding: 20px;
                text-align: center;
                background: #f9fafb;
                transition: all 0.3s ease;
            }
            
            .upload-area:hover {
                border-color: #3b82f6;
                background: #eff6ff;
            }
            
            /* Status Display */
            .status-display {
                background: #f3f4f6;
                border: 1px solid #d1d5db;
                border-radius: 6px;
                padding: 12px;
                font-size: 13px;
                color: #4b5563;
                margin-top: 15px;
            }
            
            /* Right Content Area */
            .right-content {
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                padding: 25px;
                overflow-y: auto;
            }
            
            /* Data Summary Table */
            .data-summary-container {
                margin-bottom: 30px;
            }
            
            .section-title {
                font-size: 18px;
                font-weight: 600;
                color: #111827;
                margin: 0 0 20px 0;
                padding-bottom: 10px;
                border-bottom: 2px solid #e5e7eb;
            }
            
            .data-summary-table {
                width: 100%;
                border-collapse: collapse;
                background: white;
                border-radius: 8px;
                overflow: hidden;
                box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            }
            
            .data-summary-table th {
                background: #f8fafc;
                color: #374151;
                font-weight: 600;
                padding: 12px 16px;
                text-align: left;
                border-bottom: 1px solid #e5e7eb;
                font-size: 14px;
            }
            
            .data-summary-table td {
                padding: 12px 16px;
                border-bottom: 1px solid #f3f4f6;
                font-size: 13px;
                color: #4b5563;
            }
            
            .data-summary-table tr:hover {
                background: #f9fafb;
            }
            
            .dataset-name {
                font-weight: 500;
                color: #1f2937;
            }
            
            .numeric {
                text-align: right;
                font-family: 'Courier New', monospace;
            }
            
            /* Analysis Dashboard */
            .analysis-dashboard {
                margin-top: 20px;
            }
            
            .dashboard-grid {
                display: grid;
                gap: 25px;
            }
            
            .dataset-panel {
                border: 1px solid #e5e7eb;
                border-radius: 8px;
                overflow: hidden;
                background: white;
            }
            
            .panel-header {
                background: #f8fafc;
                padding: 16px 20px;
                border-bottom: 1px solid #e5e7eb;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            
            .dataset-title {
                font-size: 16px;
                font-weight: 600;
                color: #1f2937;
                margin: 0;
            }
            
            .dataset-stats {
                display: flex;
                gap: 15px;
            }
            
            .stat-item {
                background: #e5e7eb;
                color: #4b5563;
                padding: 4px 8px;
                border-radius: 4px;
                font-size: 12px;
                font-weight: 500;
            }
            
            .charts-container {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
                gap: 20px;
                padding: 20px;
            }
            
            .chart-panel {
                border: 1px solid #f3f4f6;
                border-radius: 6px;
                overflow: hidden;
                background: #fafafa;
            }
            
            .chart-title {
                background: #f8fafc;
                padding: 10px 15px;
                margin: 0;
                font-size: 14px;
                font-weight: 500;
                color: #374151;
                border-bottom: 1px solid #e5e7eb;
            }
            
            .chart-wrapper {
                padding: 15px;
                background: white;
            }
            
            .chart-image {
                width: 100%;
                height: auto;
                display: block;
                border-radius: 4px;
            }
            
            .dashboard-summary {
                text-align: center;
                color: #6b7280;
                font-size: 13px;
                margin-top: 20px;
                padding-top: 20px;
                border-top: 1px solid #e5e7eb;
            }
            
            /* Responsive */
            @media (max-width: 1200px) {
                .main-content {
                    grid-template-columns: 1fr;
                    gap: 20px;
                }
                
                .charts-container {
                    grid-template-columns: 1fr;
                }
            }
            """
        ) as demo:
            
            # Header
            gr.HTML("""
            <div class="main-header">
                <h1 class="header-title">xlcig Notebook Enterprise Analytics Platform</h1>
                <p class="header-subtitle">Professional Data Visualization & Analysis System</p>
            </div>
            """)
            
            # Main Content Layout
            with gr.Row(elem_classes=["main-content"]):
                # Left Sidebar
                with gr.Column(elem_classes=["left-sidebar"], scale=1):
                    gr.HTML('<div class="sidebar-section"><h3 class="sidebar-title">Data Upload</h3></div>')
                    
                    file_upload = gr.File(
                        label="Select Data Files",
                        file_count="multiple",
                        file_types=[".ipynb", ".csv", ".xlsx", ".xls"],
                        elem_classes=["upload-area"]
                    )
                    
                    status_display = gr.HTML(
                        value='<div class="status-display">Ready for file upload</div>'
                    )
                    
                    gr.HTML("""
                    <div class="sidebar-section">
                        <h3 class="sidebar-title">Supported Formats</h3>
                        <ul style="margin: 0; padding-left: 20px; color: #6b7280; font-size: 13px;">
                            <li>Jupyter Notebooks (.ipynb)</li>
                            <li>CSV Files (.csv)</li>
                            <li>Excel Files (.xlsx, .xls)</li>
                        </ul>
                    </div>
                    """)
                
                # Right Content Area
                with gr.Column(elem_classes=["right-content"], scale=3):
                    data_summary = gr.HTML(
                        value='<div style="text-align: center; color: #9ca3af; padding: 50px;">Upload data files to view summary</div>'
                    )
                    
                    dashboard_output = gr.HTML(
                        value='<div style="text-align: center; color: #9ca3af; padding: 50px;">Analysis dashboard will appear here after processing</div>'
                    )
            
            # Hidden state
            language_state = gr.State(value="en")
            
            # Event handlers
            def handle_file_upload(files, language):
                if not files:
                    return [
                        '<div class="status-display" style="color: #dc2626;">No files selected</div>',
                        '<div style="text-align: center; color: #9ca3af; padding: 50px;">Upload data files to view summary</div>',
                        '<div style="text-align: center; color: #9ca3af; padding: 50px;">Analysis dashboard will appear here after processing</div>'
                    ]
                
                try:
                    summary_table, dashboard_html, status_msg = self.process_multiple_files(files, language)
                    
                    status_html = f'<div class="status-display" style="color: #059669;">✓ {status_msg}</div>'
                    
                    return [status_html, summary_table, dashboard_html]
                    
                except Exception as e:
                    error_html = f'<div class="status-display" style="color: #dc2626;">✗ Error: {str(e)}</div>'
                    return [
                        error_html,
                        '<div style="text-align: center; color: #9ca3af; padding: 50px;">Error processing files</div>',
                        '<div style="text-align: center; color: #9ca3af; padding: 50px;">Please try again</div>'
                    ]
            
            file_upload.change(
                fn=handle_file_upload,
                inputs=[file_upload, language_state],
                outputs=[status_display, data_summary, dashboard_output]
            )
            
        return demo


def main():
    """Launch the enterprise application"""
    app = XlcigNotebookApp()
    demo = app.create_interface()
    
    # Launch application
    demo.launch(
        server_name="0.0.0.0",
        server_port=7861,  # Use different port to avoid conflicts
        share=False,
        debug=True,
        show_error=True,
        inbrowser=True
    )


if __name__ == "__main__":
    main() 